<!--
 * @Author: WuFeng <763467339@qq.com>
 * @Date: 2022-04-25 21:18:06
 * @LastEditTime: 2023-05-17 22:04:33
 * @LastEditors: WuFeng <763467339@qq.com>
 * @Description:
 * @FilePath: \vue3-element-plus-web\src\views\SysManage\SysUser\index.vue
 * Copyright 版权声明
-->
<template>
  <div class="app-container">
    <div class="app-container_tree">
      <el-input v-model="filterText" placeholder="部门关键字" />
      <el-tree
        ref="deptTreeRef"
        class="filter-tree"
        :data="deptTreeData"
        :props="deptTreeProps"
        :expand-on-click-node="true"
        :highlight-current="true"
        :check-on-click-node="true"
        :filter-node-method="filterDeptTreeNode"
        @node-click="deptTreeNodeClick"
        node-key="id"
      >
        <template #default="{ node }">
          <span class="custom-tree-node">
            <span>{{ node.label }}</span>
          </span>
        </template>
      </el-tree>
    </div>
    <div class="app-container_main">
      <standard-page
        ref="crudPage"
        v-model:page="page"
        v-model:listData="listData"
        v-model:btnLoading="btnLoading"
        v-model:listLoading="listLoading"
        :options="options"
        :pageParams="pageParams"
        @on-load-data="onLoadData"
        @search-change="searchChange"
        @search-reset="resetChange"
        @refresh-change="refreshChange"
        @row-save="rowSave"
        @row-update="rowUpdate"
        @row-del="rowDel"
        @selection-change="selectionChange"
        @export-data="exportData"
      >
        <!-- 自定义操作按钮 -->
        <template #handleBtns>
        </template>
        <!-- 状态 列卡槽 -->
        <template #column_status="scope">
          <template v-for="(item, index) in ENABLED_STATE_ENUM" :key="index">
            <template v-if="scope.row.status === item.value">
              <el-tag :type="item.type">{{item.label}}</el-tag>
            </template>
          </template>
        </template>
        <!-- 表格操作列 - 自定义操作按钮 -->
        <template
          #handleColumnBtns="scope"
          v-handle-auth:RESERT_PASSWORD="{'meta': this.$route.meta}"
        >
          <el-popconfirm
            title="确定要重置密码吗？"
            @confirm="handleResetPwd(scope.row)"
          >
            <template #reference>
              <el-link
                type="primary"
                title="重置密码"
              >
                重置密码
              </el-link>
            </template>
          </el-popconfirm>
        </template>
      </standard-page>
    </div>
  </div>
</template>

<script>
import { getList as getRoleList } from '@/api/SysManage/role'
import { getTree as getDeptTree } from '@/api/SysManage/dept'
import { getList, deleteSave, resetPwd, exportData } from '@/api/SysManage/sysUser'
import { mapGetters } from 'vuex'
// 标准增删改查页面 - 组件
import StandardPage from '@/components/StandardPage/index.vue'
import { ENABLED_STATE_ENUM } from '@/config'
import { resolveBlob } from '@/utils/fs'

// 当前模块名称
const MODULE_VALUE = 'SYS_USER_MANAGE'

export default {
  name: 'SysUser',
  computed: {
    ...mapGetters([
      'drawerVisible',
      'dictData'
    ])
  },
  components: {
    StandardPage
  },
  data() {
    return {
      pageParams: {},
      filterText: '',
      deptTreeData: [],
      deptTreeProps: {
        children: 'children',
        label: 'title'
      },
      // 按钮 loading 状态
      btnLoading: false,
      // 列表 loading 状态
      listLoading: false,
      // 分页信息
      page: {
        pageNum: 1,
        total: 110,
        pageSize: 10
      },
      // 查询条件
      listQuery: {},
      // 数据
      listData: [],
      options: {
        MODULE_VALUE,
        createDrawerWidth: '30%', // 新建 抽屉弹窗宽度
        updateDrawerWidth: '30%', // 编辑 抽屉弹窗宽度
        detailDrawerWidth: '30%', // 详情 抽屉弹窗宽度
        // 自动加载数据
        autoOnLoadData: false,
        // 页面title, showHeader 为 true 时生效， 默认值： 页面标题
        title: '用户管理',
        // 结果展示区标题
        // resultTitle: '列表',
        // 是否展示 header， 默认值： true
        showHeader: true,
        // 是否展示 查询条件区域, 默认值 ： true
        showSearch: true,
        // 搜索条件标题的宽度, 默认值： 110px
        searchLabelWidth: '110px',
        // 搜索的文字， 默认值： 查询
        searchBtnText: '查询',
        // 清空的文字， 默认值： 重置
        emptyBtnText: '重置',
        // 是否展示 查询条件区域 - 【展开/折叠】 按钮， 默认值： true
        searchShowMoreBtn: false,
        // 功能按钮区 - 导出 按钮是否展示
        showExportBtn: () => {
          return this.$route.meta.handleAuth && this.$route.meta.handleAuth.EXPORT || false
        },
        // 是否展示 分页， 默认值： true
        showPage: true,
        // 是否显示表格 行多选， 默认值： false
        selection: false,
        // 是否显示表格 索引/序号 列， 默认值： false
        index: false,
        // 设置表格的序号的标题,默认为： 序号
        indexLabel: '序号',
        // 表格操作列 - 宽度
        handleColumnWidth: '180',
        // 表格操作列 - 隐藏查看按钮
        showDetailBtn: false,
        // 表格操作列 - 编辑按钮是否展示
        showUpdateBtn: (row) => {
          return true
        },
        // 表格操作列 - 删除按钮是否展示
        showDeleteBtn: (row) => {
          if (row.id === '1') {
            return false
          }
          return true
        },
        // 字段配置
        column: [
          {
            label: '用户编号',
            prop: 'code',
            width: 110 // 对应列的宽度
          },
          // {
          //   label: '用户平台',
          //   prop: 'userType',
          //   width: 90 // 对应列的宽度
          // },
          {
            label: '账号',
            prop: 'account'
            // width: 110 // 对应列的宽度
          },
          {
            show: false,
            label: '角色',
            prop: 'roleId',
            search: true, // 是否在搜索区作为查询条件展示
            searchType: 'select', // 定义搜索框的类型， 默认值： text ， 枚举： text 、 select 、 selectMultiple 、 checkbox 、 radio 、 daterange 、 datetime
            dictData: [] // searchType / formType 如果为 checked 、 radio 、 select 等需要枚举的配置此值
          },
          {
            label: '角色',
            prop: 'roleName',
            minWidth: 100 // 对应列的宽度
          },
          {
            label: '部门',
            prop: 'ancestorNames',
            minWidth: 100 // 对应列的宽度
          },
          {
            label: '昵称',
            prop: 'name',
            minWidth: 110 // 对应列的宽度
          },
          {
            label: '真实姓名',
            prop: 'realName',
            minWidth: 110 // 对应列的宽度
          },
          {
            label: '邮箱',
            prop: 'email',
            minWidth: 110 // 对应列的宽度
          },
          {
            label: '手机号码',
            prop: 'phone',
            minWidth: 110 // 对应列的宽度
          },
          // {
          //   label: '头像',
          //   prop: 'avatar',
          //   minWidth: 80 // 对应列的宽度
          // },
          // {
          //   label: '生日',
          //   prop: 'birthday',
          //   minWidth: 100 // 对应列的宽度
          // },
          // {
          //   label: '性别',
          //   prop: 'sex',
          //   align: 'center',
          //   width: 70 // 对应列的宽度
          // },
          // {
          //   label: 'IC卡ID',
          //   prop: 'icCard',
          //   width: 110 // 对应列的宽度
          // },
          {
            label: '创建时间',
            prop: 'createTime',
            width: 160, // 对应列的宽度
            align: 'center' // 水平对称方式， 默认： left ， 枚举：left、center、right
          },
          {
            show: false, // 在列表中不展示此列， 一般用于在列表不展示，在查询条件中展示
            label: '关键字', //
            prop: 'key',
            search: true, // 是否在搜索区作为查询条件展示， 默认值： false
            searchType: 'text', // 定义搜索框的类型， 默认值： text ， 枚举： text 、 select 、 selectMultiple 、 checkbox 、 radio 、 daterange 、 datetime
            searchPlaceholder: '请输入关键字', // 输入框占位文本
            searchTip: '请输入关键字', // 辅助提示语
            searchTipPlacement: 'left' // 提示语的方向
          },
          {
            label: '状态',
            prop: 'status',
            width: 100, // 对应列的宽度
            align: 'center', // 水平对称方式， 默认： left ， 枚举：left、center、right,
            search: true, // 是否在搜索区作为查询条件展示
            searchType: 'select', // 定义搜索框的类型， 默认值： text ， 枚举： text 、 select 、 selectMultiple 、 checkbox 、 radio 、 daterange 、 datetime
            dictData: ENABLED_STATE_ENUM // searchType / formType 如果为 checked 、 radio 、 select 等需要枚举的配置此值
          },
          {
            show: false, // 在列表中不展示此列， 一般用于在列表不展示，在查询条件中展示
            label: '时间',
            prop: 'dateRange',
            search: true, // 是否在搜索区作为查询条件展示
            searchType: 'daterange' // 定义搜索框的类型， 默认值： text ， 枚举： text 、 select 、 selectMultiple 、 checkbox 、 radio 、 daterange 、 datetime
          }
        ]
      },
      // 状态 枚举
      ENABLED_STATE_ENUM
    }
  },
  watch: {
    filterText(val) {
      this.$refs.deptTreeRef.filter(val)
    }
  },
  async beforeCreate() {
    const roleRes = await getRoleList({
      sataus: 1,
      current: 1,
      size: 9999
    })
    const roleResData = roleRes.data.records || []
    const dataArr = []
    for (const i in roleResData) {
      dataArr.push({
        value: roleResData[i].id,
        label: roleResData[i].roleName
      })
    }
    this.$store.dispatch('SET_DICT_LIST', {
      code: 'ROLE_LIST',
      data: dataArr
    }).then(res => {
      this.options.column[2].dictData = this.dictData.ROLE_LIST || []
    })
  },
  created() {
    // 获取部门树
    this.getDeptTree()
  },
  activated() {
  },
  deactivated() {
  },
  methods: {
    // 重置密码
    async handleResetPwd(row) {
      await resetPwd({
        id: row.id
      })
      this.$notify({
        title: '提示',
        message: '重置成功， 重置后的密码为： Zero@123456',
        type: 'success',
        duration: 10000
      })
    },
    // 获取部门树
    async getDeptTree() {
      const res = await getDeptTree()
      this.deptTreeData = res.data || []
    },
    // 点击部门树节点
    deptTreeNodeClick(data, node, event) {
      this.pageParams.currentDept = data
      this.listQuery = Object.assign({}, this.listQuery, {
        deptId: data.id
      })
      this.onLoadData()
    },
    // 搜索部门树数据
    filterDeptTreeNode(value, data) {
      if (!value) {
        return data
      }
      return data.title.indexOf(value) !== -1
    },
    // 加载数据
    onLoadData(params) {
      if (typeof params !== 'undefined') {
        this.listQuery = Object.assign({}, this.listQuery, params.query)
      }

      // 查询条件处理
      const queryParams = JSON.parse(JSON.stringify(this.listQuery))
      if (typeof queryParams.dateRange !== 'undefined') {
        if ((queryParams.dateRange).length > 0) {
          queryParams.startTime = queryParams.dateRange[0]
          queryParams.endTime = queryParams.dateRange[1]
          delete queryParams.dateRange
        } else {
          queryParams.startTime = ''
          queryParams.endTime = ''
          delete queryParams.dateRange
        }
      }

      this.btnLoading = true
      this.listLoading = true
      return getList({
        current: this.page.pageNum,
        size: this.page.pageSize,
        ...queryParams
      }).then(response => {
        this.listData = response.data.records || []
        this.page.total = response.data.total || 0

        this.btnLoading = false
        this.listLoading = false
      }).catch(err => {
        err
        this.btnLoading = false
        this.listLoading = false
      })
    },
    // 点击搜索后执行方法
    searchChange(params) {
      console.log('点击搜索按钮回调', params)
    },
    // 点击清空的执行方法
    resetChange(params) {
      console.log('清空回调', params)
    },
    // 刷新数据
    refreshChange(params) {
      console.log('刷新数据', params)
    },
    // 新增数据
    rowSave(params) {
      console.log('新增数据', params)
    },
    // 修改数据
    rowUpdate(params) {
      console.log('修改数据', params)
    },
    // 删除数据
    rowDel(params) {
      deleteSave({
        ids: params.data.id
      }).then(response => {
        this.$notify({
          title: '提示',
          message: '删除成功',
          type: 'success',
          duration: 2000
        })
        this.onLoadData()
      }).catch(err => {
        err
      })
    },
    // selectionChange
    selectionChange(data) {
      console.log('selectionChange:', data)
    },
    // 点击 导出 回调方法
    async exportData(params) {
      if (typeof params !== 'undefined') {
        this.listQuery = Object.assign({}, this.listQuery, params.query)
      }
      // 查询条件处理
      const queryParams = JSON.parse(JSON.stringify(this.listQuery))
      if (typeof queryParams.dateRange !== 'undefined') {
        if ((queryParams.dateRange).length > 0) {
          queryParams.startTime = queryParams.dateRange[0]
          queryParams.endTime = queryParams.dateRange[1]
          delete queryParams.dateRange
        } else {
          queryParams.startTime = ''
          queryParams.endTime = ''
          delete queryParams.dateRange
        }
      }
      this.btnLoading = true
      return exportData({
        ...queryParams
      }).then(response => {
        resolveBlob(response)
        this.$notify({
          title: '成功',
          message: '导出成功',
          type: 'success',
          duration: 2000
        })
        this.btnLoading = false
      }).catch(err => {
        err
        this.btnLoading = false
      })
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
.app-container{
  padding-left: 240px;
  &_tree{
    float: left;
    width: 220px;
    padding: 10px;
    background-color: #fff;
    margin-left: -240px;
  }
  &_main{
    width: 100%;
  }
}
</style>
